home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / dkbuts.zip / SA2DKB.C < prev    next >
C/C++ Source or Header  |  1991-05-16  |  11KB  |  374 lines

  1. /*****************************************************************************
  2. *
  3. *                                    sa2dkb.c
  4. *
  5. *   from DKBTrace (c) 1990  David Buck
  6. *
  7. *  This program reads a Sculpt-Animate 3D format scene file and generates an
  8. *  output file that may be read in to DKBTrace.
  9. *
  10. *
  11. * This software is freely distributable. The source and/or object code may be
  12. * copied or uploaded to communications services so long as this notice remains
  13. * at the top of each file.  If any changes are made to the program, you must
  14. * clearly indicate in the documentation and in the programs startup message
  15. * who it was who made the changes. The documentation should also describe what
  16. * those changes were. This software may not be included in whole or in
  17. * part into any commercial package without the express written consent of the
  18. * author.  It may, however, be included in other public domain or freely
  19. * distributed software so long as the proper credit for the software is given.
  20. *
  21. * This software is provided as is without any guarantees or warranty. Although
  22. * the author has attempted to find and correct any bugs in the software, he
  23. * is not responsible for any damage caused by the use of the software.  The
  24. * author is under no obligation to provide service, corrections, or upgrades
  25. * to this package.
  26. *
  27. * Despite all the legal stuff above, if you do find bugs, I would like to hear
  28. * about them.  Also, if you have any comments or questions, you may contact me
  29. * at the following address:
  30. *
  31. *     David Buck
  32. *     22C Sonnet Cres.
  33. *     Nepean Ontario
  34. *     Canada, K2H 8W7
  35. *
  36. *  I can also be reached on the following bulleton boards:
  37. *
  38. *     OMX              (613) 731-3419
  39. *     Mystic           (613) 596-4249  or  (613) 596-4772
  40. *
  41. *  Fidonet:   1:163/109.9
  42. *  Internet:  dbuck@ccs.carleton.ca
  43. *  The "You Can Call Me RAY" BBS    (708) 358-5611
  44. *
  45. *  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  46. *
  47. *     The "You Can Call Me RAY" BBS (708) 358-5611
  48. *     The Information Exchange BBS  (708) 945-5575
  49. *
  50. *****************************************************************************/
  51.  
  52. #include <stdio.h>
  53. #include <stdlib.h>        /* contains "malloc" and "exit" prototypes */
  54. #include <string.h>
  55.  
  56. #define DBL double
  57.  
  58. typedef struct {
  59.    unsigned short Red, Green, Blue, Alpha;
  60.    } IMAGE_COLOUR;
  61.  
  62. IMAGE_COLOUR *iff_colour_map;
  63. int colourmap_size;
  64. FILE *f, *out, *out2, *texture_file;
  65.  
  66. struct Chunk_Header_Struct {
  67.    long name;
  68.    long size;
  69.    };
  70.  
  71. typedef struct Chunk_Header_Struct CHUNK_HEADER;
  72.  
  73. static CHUNK_HEADER Chunk_Header;
  74.  
  75.  
  76. /* function prototypes */
  77.  
  78. /* char *malloc(unsigned int size);    (defined in stdlib.h) */
  79. void read_iff_file(void);
  80. void close_all(void);
  81. void add_texture(unsigned int, unsigned int, unsigned int, unsigned int);
  82. void iff_error (void);
  83. int read_byte (FILE *);
  84. int read_word (FILE *);
  85. long read_long (FILE *);
  86. void Read_Chunk_Header (FILE *, CHUNK_HEADER *);
  87.  
  88.  
  89. DBL *vertices_x, *vertices_y, *vertices_z;
  90. DBL max_x, max_y, max_z, min_x, min_y, min_z;
  91. #define FABS(x) ((x<0.0)?-x:x)
  92.  
  93. #define FORM 0x464f524dL
  94. #define SC3D 0x53433344L
  95. #define VERT 0x56455254L
  96. #define FACE 0x46414345L
  97.  
  98. #define CMPNONE 0
  99.  
  100. char *Textures[7] = {"Dull", "Shiny", "Mirror", "Luminous", "Glass", "Metal", "Glass2"};
  101.  
  102. #define TEXTURE_TABLE_SIZE 16300
  103. unsigned long *texture_table;
  104. unsigned int texture_table_size = 0;
  105.  
  106. char outfile[80];
  107.  
  108. void close_all()
  109.    {
  110.    if (out != NULL) {
  111.       fclose (out);
  112.       unlink ("triangle.tmp");
  113.       }
  114.  
  115.    if (out2 != NULL) {
  116.       fclose (out2);
  117.       unlink (outfile);
  118.       }
  119.  
  120.    if (texture_file != NULL) {
  121.       fclose (texture_file);
  122.       unlink ("textures.tmp");
  123.       }
  124.  
  125.    if (f != NULL) {
  126.       fclose (f);
  127.       }
  128.    }
  129.  
  130. void add_texture (texture, red, green, blue)
  131.    unsigned int texture, red, green, blue;
  132.    {
  133.    unsigned long texture_id;
  134.    int i;
  135.  
  136.    texture_id = ((unsigned long)texture << 24) | ((unsigned long)red << 16) | (green << 8) | blue;
  137.  
  138.    for (i = 0; (unsigned) i < texture_table_size; i++)
  139.       if (texture_id == texture_table[i])
  140.          return;
  141.  
  142.    texture_table[texture_table_size++] = texture_id;
  143.  
  144.    if (texture_table_size >= TEXTURE_TABLE_SIZE) {
  145.       fprintf (stderr, "Colour table overflow\n");
  146.       close_all();
  147.       exit(1);
  148.       }
  149.  
  150.    fprintf (texture_file, "DECLARE %s_%d_%d_%d = TEXTURE %s COLOUR RED %f GREEN %f BLUE %f END_TEXTURE\n",
  151.             Textures[texture], red, green, blue, 
  152.             Textures[texture], red/255.0, green/255.0, blue/255.0);
  153.    }
  154.  
  155. void iff_error ()
  156.    {
  157.    fprintf (stderr, "Invalid iff file\n");
  158.    close_all();
  159.    exit(1);
  160.    }
  161.  
  162. int read_byte(f)
  163.    FILE *f;
  164.    {
  165.    int c;
  166.    if ((c = getc(f)) == EOF)
  167.       iff_error();
  168.    return (c);
  169.    }
  170.  
  171. int read_word(f)
  172.    FILE *f;
  173.    {
  174.    int result;
  175.  
  176.    result = read_byte(f)*256;
  177.    result += read_byte(f);
  178.    return (result);
  179.    }
  180.  
  181. long read_long(f)
  182.    FILE *f;
  183.    {
  184.    int i;
  185.    long result;
  186.  
  187.    result = 0;
  188.    for (i = 0 ; i < 4 ; i++)
  189.       result = result * 256 + read_byte(f);
  190.  
  191.    return (result);
  192.    }
  193.  
  194. void Read_Chunk_Header (f, dest)
  195.    FILE *f;
  196.    CHUNK_HEADER *dest;
  197.    {
  198.    dest->name = read_long(f);
  199.    dest->size = (int) read_long(f);
  200.    }
  201.  
  202. void read_iff_file()
  203.    {
  204.    int i;
  205.    int vert1, vert2, vert3;
  206.    unsigned int texture;
  207.    unsigned int red_int, green_int, blue_int;
  208.  
  209.    max_x = max_y = max_z = -10000000.0;
  210.    min_x = min_y = min_z = 10000000.0;
  211.  
  212.    while (1) {
  213.       Read_Chunk_Header(f, &Chunk_Header);
  214.       switch ((int) Chunk_Header.name) {
  215.          case FORM: if (read_long(f) != SC3D)
  216.                        iff_error();
  217.                     break;
  218.  
  219.          case VERT:
  220.                     if ((vertices_x = (DBL *)
  221.                         malloc ((unsigned)Chunk_Header.size * (sizeof(DBL)/sizeof(long)))) == NULL) {
  222.                         fprintf (stderr, "Cannot allocate memory for vertices_x array\n");
  223.                         close_all();
  224.                         exit(1);
  225.                         }
  226.                     if ((vertices_y = (DBL *)
  227.                         malloc ((unsigned)Chunk_Header.size * (sizeof(DBL)/sizeof(long)))) == NULL) {
  228.                         fprintf (stderr, "Cannot allocate memory for vertices_y array\n");
  229.                         close_all();
  230.                         exit(1);
  231.                         }
  232.                     if ((vertices_z = (DBL *)
  233.                         malloc ((unsigned)Chunk_Header.size * (sizeof(DBL)/sizeof(long)))) == NULL) {
  234.                         fprintf (stderr, "Cannot allocate memory for vertices_z array\n");
  235.                         close_all();
  236.                         exit(1);
  237.                         }
  238.                     for (i = 0 ; (long) i < Chunk_Header.size/12L ; i++) {
  239.                        vertices_x[i] = read_long(f) / 10000.0;
  240.                        if (vertices_x[i] < min_x)
  241.                           min_x = vertices_x[i];
  242.                        if (vertices_x[i] > max_x)
  243.                           max_x = vertices_x[i];
  244.  
  245.                        vertices_y[i] = read_long(f) / 10000.0;
  246.                        if (vertices_y[i] < min_y)
  247.                           min_y = vertices_y[i];
  248.                        if (vertices_y[i] > max_y)
  249.                           max_y = vertices_y[i];
  250.  
  251.                        vertices_z[i] = read_long(f) / 10000.0;
  252.                        if (vertices_z[i] < min_z)
  253.                           min_z = vertices_z[i];
  254.                        if (vertices_z[i] > max_z)
  255.                           max_z = vertices_z[i];
  256.                        }
  257.                     break;
  258.  
  259.          case FACE: for (i = 0 ; (long) i < Chunk_Header.size/16L ; i++) {
  260.                        vert1 = (int) read_long(f);
  261.                        vert2 = (int) read_long(f);
  262.                        vert3 = (int) read_long(f);
  263.                        red_int = read_byte(f);
  264.                        green_int = read_byte(f);
  265.                        blue_int = read_byte(f);
  266.  
  267.                        texture = read_byte(f);
  268.                        texture &= 0x07;        /* mask upper bits */
  269.                        add_texture (texture, red_int, green_int, blue_int);
  270.  
  271.                        fprintf (out, "TRIANGLE <%f %f %f> <%f %f %f> <%f %f %f> TEXTURE %s_%d_%d_%d END_TEXTURE END_TRIANGLE\n",
  272.                           vertices_x[vert1], vertices_y[vert1], vertices_z[vert1],
  273.                           vertices_x[vert2], vertices_y[vert2], vertices_z[vert2],
  274.                           vertices_x[vert3], vertices_y[vert3], vertices_z[vert3],
  275.                           Textures[texture], red_int, green_int, blue_int);
  276.                        }
  277.                     return;
  278.  
  279.          default:
  280.             for (i = 0 ; (long) i < Chunk_Header.size ; i++)
  281.                if (getc(f) == EOF)
  282.                   iff_error();
  283.             break;
  284.          }
  285.       }
  286.    }
  287.  
  288. void main (argc, argv)
  289.    int argc;
  290.    char **argv;
  291.    {
  292.    int c;
  293.  
  294.    if (argc != 3) {
  295.       fprintf (stderr, "Usage: %s <scene-file> <output-file>\n", argv[0]);
  296.       exit (1);
  297.       }
  298.    
  299.    f = out = out2 = texture_file = NULL;
  300.  
  301.    strcpy(outfile, argv[2]);
  302.  
  303.    if ((texture_table = (unsigned long *) malloc((unsigned int)TEXTURE_TABLE_SIZE * sizeof (unsigned long))) == NULL) {
  304.       fprintf (stderr, "Cannot allocate memory for texture table\n");
  305.       exit(1);
  306.       }
  307.  
  308.    if ((f = fopen(argv[1], "rb")) == NULL) {
  309.       fprintf (stderr, "Cannot open IFF file %s\n", argv[1]);
  310.       exit(1);
  311.       }
  312.  
  313.    if ((out = fopen("triangle.tmp", "w")) == NULL) {
  314.       fprintf (stderr, "Cannot open temporary file triangle.tmp\n");
  315.       close_all();
  316.       exit(1);
  317.       }
  318.    
  319.    if ((texture_file = fopen("textures.tmp", "w")) == NULL) {
  320.       fprintf (stderr, "Cannot open temporary file textures.tmp\n");
  321.       close_all();
  322.       exit(1);
  323.       }
  324.  
  325.    fprintf(out, "\nOBJECT\n   UNION\n");
  326.    read_iff_file();
  327.    fprintf(out, "   END_UNION\n");
  328.    fprintf(out, "   BOUNDED_BY\n      INTERSECTION\n");
  329.    fprintf(out, "         PLANE <1.0  0.0  0.0> %1.02f END_PLANE\n", FABS(max_x) * 1.01);
  330.    fprintf(out, "         PLANE <-1.0 0.0  0.0> %1.02f END_PLANE\n", FABS(min_x) * 1.01);
  331.    fprintf(out, "         PLANE <0.0  1.0  0.0> %1.02f END_PLANE\n", FABS(max_y) * 1.01);
  332.    fprintf(out, "         PLANE <0.0 -1.0  0.0> %1.02f END_PLANE\n", FABS(min_y) * 1.01);
  333.    fprintf(out, "         PLANE <0.0  0.0  1.0> %1.02f END_PLANE\n", FABS(max_z) * 1.01);
  334.    fprintf(out, "         PLANE <0.0  0.0 -1.0> %1.02f END_PLANE\n", FABS(min_z) * 1.01);
  335.    fprintf(out, "      END_INTERSECTION\n   END_BOUND\n   \nEND_OBJECT\n");
  336.    printf ("X values range from %f to %f\n", min_x, max_x);
  337.    printf ("Y values range from %f to %f\n", min_y, max_y);
  338.    printf ("Z values range from %f to %f\n", min_z, max_z);
  339.    fclose(f);
  340.    fflush(out);
  341.    fclose(out);
  342.    fflush(texture_file);
  343.    fclose(texture_file);
  344.    
  345.    if ((out2 = fopen (argv[2], "w")) == NULL) {
  346.       fprintf (stderr, "Cannot open output file %s\n", argv[2]);
  347.       exit(1);
  348.       }
  349.  
  350.    if ((out = fopen("triangle.tmp", "r")) == NULL) {
  351.       fprintf (stderr, "Cannot open temporary file triangle.tmp\n");
  352.       close_all();
  353.       exit(1);
  354.       }
  355.    
  356.    if ((texture_file = fopen("textures.tmp", "r")) == NULL) {
  357.       fprintf (stderr, "Cannot open temporary file textures.tmp\n");
  358.       close_all();
  359.       exit(1);
  360.       }
  361.    
  362.    while ((c = getc(texture_file)) != EOF)
  363.       putc (c, out2);
  364.  
  365.    while ((c = getc(out)) != EOF)
  366.       putc (c, out2);
  367.  
  368.    fflush(out2);
  369.    fclose(out2);
  370.    out2 = NULL;        /* make sure close_all doesn't delete out2 file */
  371.    close_all();
  372.    exit(0);
  373.    }
  374.